/*
    nspire-gamekit - a simple homebrew game framework
    Copyright (C) 2011  Daniel Tang

    This program is gameAutoFree software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the gameAutoFree Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
extern "C" {
    #include <os.h>
}
#include "ndlesscpp.h"
#include "autorelease.h"
#include "timer.h"
#include "types/timer.h"
#include "debug.h"

/* Oh noes, another doubley linked list :( */

typedef struct game_timer_t game_timer_t;
struct game_timer_t {
    game_timer_t *next;
    game_timer_t *prev;
    NGKTimerBase *timer;
};

static game_timer_t* firstElement = NULL;
static game_timer_t* lastElement = NULL;
static void gameTimerFree(game_timer_t* node);

void gameTimerTick(NGKGameTime ticks) {
    game_timer_t *node = firstElement;
    game_timer_t *next = node;
    
    while (node) { 
        next = node->next;
        node->timer->update(ticks);
        node = next;
    }
}

void gameTimerRemoveFromQueue(NGKTimerBase *timer) {
    game_timer_t *node = firstElement;
    game_timer_t *next = node;
    
    while (node) { 
        next = node->next;
        if (node->timer == timer) {
            gameTimerFree(node);
            break;
        }
        node = next;
    }
}


void gameTimerAddToQueue(NGKTimerBase *timer) {
    if (!timer) return;

    game_timer_t *node = (game_timer_t*) gameAutoMalloc(sizeof(game_timer_t));
    if (!node) return;
    
    node->next = NULL;
    node->prev = NULL;
    
    node->timer = timer;
    
    if (firstElement == NULL) {
        firstElement = node;
    }
    if (lastElement) {
        lastElement->next = node;
        node->prev = lastElement;
    }
    lastElement = node;

}

static void gameTimerFree(game_timer_t* node) {
    /* Unlink from the double linked list */
    if (node->prev) node->prev->next = node->next;
    if (node->next) node->next->prev = node->prev;
    
    if (firstElement == node) firstElement = node->next;
    if (lastElement == node) lastElement = node->prev;
    
    gameAutoFree(node);
}
